<html xmlns="http://www.w3.org/1999/xhtml" id="animation">
<head>
    <title>Animation</title>
</head>

<body>
<h1>Animation </h1>


<h2>Introduction</h2>
<p>
Laszlo applications have a fluid, dynamic feel that allow you to guide the user's experience. This fluidity is achieved with <dfn>animators</dfn>,
which change the value of an object's attribute over a specified time duration. In this tutorial we'll start by showing the code for some short applications that allow you to see
the essential simplicity of coding with animators.  A little further down there are interactive examples that are a little more complicated but allow you to see animation in action.
</p>
<todo>
Animation
 note: this in not animation in the flash movie sense
</todo>
<p>For example, the following application defines an animator for a window that moves it to a position of x=100 over 1 second (1000 milliseconds). The animator is an instance of <classname>LzAnimator</classname>, and is defined by using the <tagname>animator</tagname> tag.</p>

<example extract="false" title="A simple animator">
&lt;canvas height="100" width="500"&gt;
  &lt;window&gt;
    &lt;animator attribute="x" to="100" duration="1000"/&gt;
  &lt;/window&gt;
&lt;/canvas&gt;
</example>

<p>
An animator starts with the current value of an attribute unless otherwise specified.  
In the next example the application defines an animator for a window that first moves the window to a position 
of <code>x="50"</code>, and then animates the window to a position of <code>x="100"</code> over 1 second.
</p>

<example extract="false" title="Specifying starting conditions">
&lt;canvas height="100" width="500"&gt;
  &lt;window x="50"&gt;
    &lt;animator attribute="x" from="50" to="100" duration="1000"/&gt;
  &lt;/window&gt;
&lt;/canvas&gt;
</example>

<p>
Animators, by default, change an object's attribute by easing in and out of the <attribute>from</attribute> and 
<attribute>to</attribute> values. Running the above sample applications shows a window that  accelerates in and out of its 
position. This nonlinear behavior can be minimally controlled with the use of the <attribute>motion</attribute> attribute. 
For example, the following  code shows a window which moves linearly across the screen, in contrast to examples above. 
The values for the motion tag are: <code>easeboth</code>, <code>easein</code>, <code>easeout</code>, and <code>linear</code>.
</p>
 
<example extract="false" title="linear movement">
&lt;canvas height="100" width="500"&gt;
  &lt;window&gt;
    &lt;animator attribute="x" to="100" duration="1000" motion="linear"/&gt;
  &lt;/window&gt;
&lt;/canvas&gt;
</example>

<p>
Animators, like views, can be named so that they can be controlled later via scripts. This next example shows a common practice to activate an animator when a view is clicked, rather than when a view is first instantiated. Animators can be initially dormant by setting <code>start="false"</code>, and then activated on demand by calling its <method>start</method> method.
</p>

<example title="Controlling animation with a script">
&lt;canvas height="100" width="500"&gt;
  &lt;view bgcolor="red" width="100" height="100" <em>onclick="this.myAnimator.doStart()"</em>&gt;
    &lt;animator name="myAnimator" attribute="x" to="100" duration="1000" start="false"/&gt;
  &lt;/view&gt;
&lt;/canvas&gt;
</example>

<p>
Animators can also animate objects relative to their current values.
This means that the goal of the animator is actually the "to" value
<em>plus</em> the objects's current value. Starting with the example
above, and including relative="true" to the set of attributes, creates
a view that animates 100 pixels to the right every time it is clicked.
</p>

<example title="Relative animation">
&lt;canvas height="100" width="500"&gt;
  &lt;view bgcolor="red" width="100" height="100" onclick="this.myAnimator.doStart()"&gt;
    &lt;animator name="myAnimator" attribute="x" to="100" duration="1000"
              start="false" <em>relative="true"</em>/&gt;
  &lt;/view&gt;
&lt;/canvas&gt;
</example>

<p> 
More than one animator can be added to an object, and the set will be processed simultaneously. The code below shows an object moving diagonally by using both "x" and "y" animators.
</p>

<example extract="false" >
&lt;canvas height="100" width="500"&gt;
  &lt;view bgcolor="red" width="100" height="100" &gt;
    &lt;animator attribute="x" to="100" duration="1000"/&gt;
    &lt;animator attribute="y" to="100" duration="1000"/&gt;
  &lt;/view&gt;
&lt;/canvas&gt;
</example>

<p>To process the two animators above sequentially, i.e. one after the
other, you use the <tagname link="true">animatorgroup</tagname> tag,
explained below.</p>

<h3>Preview of comparative examples</h3>

<p>The following examples illustrate various uses of the <tagname
link="true">animator</tagname> and <tagname
link="true">animatorgroup</tagname> tags.  Notice that below each
example there are "Test" and "Reset" buttons. The Test button causes
the animation code to be executed; the Reset button brings the
examples back to their initial state. Use these examples to see how
different animation techniques compare to each other.</p>

<p>
These applications rely on two support files, <a href="supportclasses.lzx?lzt=source">supportclasses.lzx</a> and <a href="richbutton.lzx?lzt=source">richbutton.lzx. </a> 
References to these files and associated fonts are included in <a href="animation_library.lzx?lzt=source">animation_library.lzx.</a>
</p>

<p>The following example shows the effect of animating the
<attribute>opacity</attribute>, <attribute>rotation</attribute>,
<attribute>height</attribute>, <attribute>width</attribute>, and
<attribute>x</attribute> and <attribute>y</attribute> placement of
simple views.  Click on any red square to see the animation of the
named attribute, or press "test" to see them all at once.</p>

<example title="Basic Animation">
&lt;canvas width="800" height="200" bgcolor="0xE5E1B0" &gt;
  &lt;!-- INCLUDES That provide framework for the example --&gt;
  &lt;include href="../animation_library.lzx"/&gt;
  
  &lt;!-- The EXAMPLE itself--&gt;
  &lt;view id="tutorial1" height="600" width="${parent.width}" visible="true"&gt;
    &lt;ruler name="rlr" height="3000" y="0"/&gt;
    &lt;view height="30"/&gt;
    &lt;view height="120" y="30"&gt;
      &lt;view x="50"&gt;
        &lt;boxtitle label="opacity"/&gt;
        &lt;boxtitle label="rotation"/&gt;
        &lt;boxtitle label="width"/&gt;
        &lt;boxtitle label="height"/&gt;
        &lt;boxtitle label="x"/&gt;
        &lt;boxtitle label="y"/&gt;
        &lt;simplelayout axis="x" spacing="51"/&gt;
      &lt;/view&gt;
      &lt;view y="20"&gt;<em>
        &lt;box id="B1" x="50" onclick="this.anm.doStart()"&gt;
          &lt;animator name="anm" attribute="opacity"  to=".5"  duration="500" start="false"/&gt;
        &lt;/box&gt;
        &lt;box id="B2" x="150" onclick="this.anm.doStart()"&gt;
          &lt;animator name="anm" attribute="rotation" to="45"  duration="500" start="false"/&gt;
        &lt;/box&gt;
        &lt;box id="B3" x="250" onclick="this.anm.doStart()"&gt;
          &lt;animator name="anm" attribute="width"    to="99"  duration="500" start="false"/&gt;
        &lt;/box&gt;
        &lt;box id="B4" x="350" onclick="this.anm.doStart()"&gt;
          &lt;animator name="anm" attribute="height"   to="100" duration="500" start="false"/&gt;
        &lt;/box&gt;
        &lt;box id="B5" x="450" onclick="this.anm.doStart()"&gt;
          &lt;animator name="anm" attribute="x"        to="500" duration="500" start="false"/&gt;
        &lt;/box&gt;
        &lt;box id="B6" x="550" onclick="this.anm.doStart()"&gt;
          &lt;animator name="anm" attribute="y"        to="50"  duration="500" start="false"/&gt;
        &lt;/box&gt;</em>
      &lt;/view&gt;
      &lt;simplelayout axis="y" spacing="5"/&gt;
    &lt;/view&gt;
    
    &lt;!-- The TEST and RESET buttons --&gt;
    &lt;view x="50"   y="150" width="${parent.width - 50}"&gt;
      &lt;richbutton label="Test" x="50" cap="rightsheer"
                  onclick="B1.anm.doStart();
                           B2.anm.doStart();
                           B3.anm.doStart();
                           B4.anm.doStart();
                           B5.anm.doStart();
                           B6.anm.doStart();
                           "/&gt;
      &lt;richbutton label="Reset" cap="leftsheer"
                  onclick="B1.setOpacity(1);
                           B2.setRotation(0);
                           B3.setWidth(49);
                           B4.setHeight(49);
                           B5.setX(450);
                           B6.setY(0);
                           this.parent.P2.setDisplay(' ');
                           "/&gt;
      &lt;simplelayout axis="x"/&gt;
    &lt;/view&gt;
  &lt;/view&gt;
&lt;/canvas&gt;
</example>

<h2>Absolute vs. relative animation</h2>

<p>The following example shows the difference between relative and
absolute animation. By default, <attribute>relative</attribute> is set
to <code>false</code>, which means that animation of an attribute is
calculated relative to that attribute's <em>initial</em> value.  When
<attribute>relative</attribute> is set to <code>true</code>, the
animation is relative to the value of that attribute when the animator
is invoked.  Click on each of the red squares a few times to see the
difference.</p>

<example title="Absolute and relative">
&lt;canvas width="800" height="200" bgcolor="0xE5E1B0" &gt;
  &lt;!-- INCLUDES That provide framework for the example --&gt;
  &lt;include href="../animation_library.lzx"/&gt;
  
  &lt;!-- RELATIVE ANIMATION EXAMPLE --&gt;
  &lt;view id="tutorial2" height="400" width="${parent.width}" visible="true"&gt;
    &lt;ruler name="rlr" height="300" y="0"/&gt;
    &lt;view height="30"/&gt;
    &lt;view height="120"&gt;
      &lt;view y="40" visible="true"&gt;
        &lt;view&gt;
          &lt;text&gt;Absolute&lt;/text&gt;<em>
            &lt;box id="B7" x="50" onclick="this.anm.doStart()"&gt;
              &lt;animator name="anm" attribute="x" to="200"  duration="500" start="false"/&gt;
            &lt;/box&gt;</em>
          &lt;/view&gt;
          
          &lt;view&gt;
            &lt;text&gt;Relative&lt;/text&gt;<em>
              &lt;box id="B8" x="50" onclick="this.anm.doStart()"&gt;
                &lt;animator name="anm" attribute="x" to="200"  duration="500"
                          start="false" relative="true"/&gt;
              &lt;/box&gt;</em>
            &lt;/view&gt;
          &lt;simplelayout axis="y" spacing="5"/&gt;
        &lt;/view&gt;
      &lt;/view&gt;
      
      &lt;!-- The TEST and RESET buttons --&gt;
      &lt;view x="50" y="150"&gt;
        &lt;richbutton label="Test" x="50" cap="rightsheer"
                    onclick="B7.anm.doStart();B8.anm.doStart()"/&gt;
        &lt;richbutton label="Reset" cap="leftsheer"
                    onclick="B7.setX(50);B8.setX(50);"/&gt;
      &lt;simplelayout axis="x"/&gt;
    &lt;/view&gt;
  &lt;/view&gt;
&lt;/canvas&gt;
</example>

<h2>Using the <attribute>from</attribute> attribute</h2>

<p>The <attribute>from</attribute> attribute indicates the starting
value from which the animation is to begin. If the object is not at
that value, it first assumes it and then begins the animation.  In the
example below, the animated attribute is <attribute>x</attribute>,,
the horizontal placement. The <attribute>from</attribute> value in
each case is <code>200</code>, and the <attribute>to</attribute> value
is <code>100</code>. Before the specified animation begins, the object
first moves by setting its <attribute>x</attribute> value to
<code>100</code>.  In the absolute case, the object animates to
<code>x=100</code>, where <varname>x</varname> is calculated relative
to the object's <em>initial</em> value.  In the second case, the
object moves until <code>x=100</code>, where <varname>x</varname> is
calculated relative to its value at the start of the animation.</p>

<example title="Using the &quot;from&quot; attribute">
&lt;canvas width="800" height="200" bgcolor="0xE5E1B0" &gt;
  &lt;!-- INCLUDES That provide framework for the example --&gt;
  &lt;include href="../animation_library.lzx"/&gt;
  
  &lt;!-- The EXAMPLE itself--&gt;
  &lt;view id="tutorial2" height="400" width="${parent.width}" visible="true"&gt;
    &lt;ruler name="rlr" height="300" y="0"/&gt;
    &lt;view height="30"/&gt;
    &lt;view height="120" y="40"&gt;<em>
      &lt;view&gt;
        &lt;text&gt;absolute&lt;/text&gt;
        &lt;box id="B9" x="50" onclick="this.anm.doStart()"&gt;
          &lt;animator name="anm" attribute="x" from="200" to="100"
                    duration="500" start="false"/&gt;
        &lt;/box&gt;
      &lt;/view&gt;
      
      &lt;view&gt;
        &lt;text&gt;relative&lt;/text&gt;
        &lt;box id="B10" x="50" onclick="this.anm.doStart()"&gt;
          &lt;animator name="anm" attribute="x" from="200" to="100"
                    duration="500" start="false" relative="true"/&gt;
        &lt;/box&gt;
      &lt;/view&gt;</em>
      &lt;simplelayout axis="y" spacing="5"/&gt;
    &lt;/view&gt;
  &lt;/view&gt;
  
  &lt;!-- The TEST and RESET buttons --&gt;
  &lt;view x="50" y="150"&gt;
    &lt;richbutton label="Test" x="50" cap="rightsheer"
               onclick="B9.anm.doStart();B10.anm.doStart()"/&gt;
    &lt;richbutton label="Reset" cap="leftsheer"
               onclick="B9.setX(50);B10.setX(50);this.parent.P2.setDisplay(' ');"/&gt;
    &lt;simplelayout axis="x"/&gt;
  &lt;/view&gt;
&lt;/canvas&gt;
</example>

<h2>Using the <attribute>motion</attribute> attribute</h2>

<p>The <attribute>motion</attribute> attribute allows you to specify
whether the animation accelerates ("ease out"), decelerates ("ease
in"), both accelerates and decelerates ("ease both"), or is at a
constant rate (linear).</p>

<example title="Using the &quot;motion&quot; attribute">
&lt;canvas width="800" height="300" bgcolor="0xE5E1B0" &gt;
  &lt;!-- INCLUDES That provide framework for the example --&gt;
  &lt;include href="../animation_library.lzx"/&gt;
  
  &lt;!-- The EXAMPLE itself--&gt;
  &lt;view id="tutorial2" height="400" width="${parent.width}" visible="true"&gt;
    &lt;ruler name="rlr" height="300" y="0"/&gt;
    &lt;view height="30"/&gt;
    &lt;view height="200" y="40"&gt;
      &lt;view&gt;
        &lt;text&gt;easeboth&lt;/text&gt;<em>
        &lt;box id="B11" x="50" onclick="this.anm.doStart()"&gt;
          &lt;animator name="anm" attribute="x" to="600"
                    duration="1000" start="false" motion="easeboth"/&gt;
        &lt;/box&gt;
      &lt;/view&gt;
      
      &lt;view&gt;
        &lt;text&gt;easein&lt;/text&gt;
        &lt;box id="B12" x="50" onclick="this.anm.doStart()"&gt;
          &lt;animator name="anm" attribute="x" to="600"
                    duration="1000" start="false" motion="easein"/&gt;
        &lt;/box&gt;
      &lt;/view&gt;
      
      &lt;view&gt;
        &lt;text&gt;easeout&lt;/text&gt;
        &lt;box id="B13" x="50" onclick="this.anm.doStart()"&gt;
          &lt;animator name="anm" attribute="x" to="600"
                    duration="1000" start="false" motion="easeout"/&gt;
        &lt;/box&gt;
      &lt;/view&gt;
      
      &lt;view&gt;
        &lt;text&gt;linear&lt;/text&gt;
        &lt;box id="B14" x="50" onclick="this.anm.doStart()"&gt;
          &lt;animator name="anm" attribute="x" to="600"
                    duration="1000" start="false" motion="linear"/&gt;
        &lt;/box&gt;</em>
      &lt;/view&gt;
      &lt;simplelayout axis="y" spacing="5"/&gt;
    &lt;/view&gt;
  &lt;/view&gt;
  
  &lt;!-- The TEST and RESET buttons --&gt;
  &lt;view x="50" y="260"&gt;
    &lt;richbutton label="Test" x="50" cap="rightsheer"
                 onclick="B11.anm.doStart();
                          B12.anm.doStart();
                          B13.anm.doStart();
                          B14.anm.doStart()"/&gt;
    &lt;richbutton label="Reset" cap="leftsheer"
                 onclick="B11.setX(50);
                          B12.setX(50);
                          B13.setX(50);
                          B14.setX(50);
                          this.parent.P2.setDisplay(' ');"/&gt;
    &lt;simplelayout axis="x"/&gt;
  &lt;/view&gt;
&lt;/canvas&gt;
</example>

<h2>Tags vs Script</h2>
<p>
In Laszlo applications you can achieve the same result by using XML tags or JavaScript APIs. The examples above have demonstrated how to use the <tagname>animator</tagname> tag.  Alternatively
you can use the <method link="true">LzNode.animate</method> method in script statements. The following example contrasts tag and script approaches to animating views.
</p>

<example title="The &quot;bounce effect &quot;">
&lt;canvas width="800" height="390" bgcolor="0xE5E1B0" &gt;
  &lt;!-- INCLUDES That provide framework for the example --&gt;
  &lt;include href="../animation_library.lzx"/&gt;
  
  &lt;!-- The EXAMPLE itself--&gt;
  &lt;view id="tutorial2" height="400" width="${parent.width}" visible="true"&gt;
    &lt;ruler name="rlr" height="350" y="0"/&gt;
    &lt;view height="30"/&gt;
    &lt;view height="200" y="40"&gt;<em>
      &lt;box id="B15" x="50" onclick="this.ax1.doStart(); this.ax2.doStart()"&gt;
        &lt;animator name="ax1" attribute="x" to="400"
                  duration="1000" motion="easeout" start="false"/&gt;
        &lt;animator name="ax2" attribute="x" to="300"
                  duration="1000" motion="easein"  start="false"/&gt;
      &lt;/box&gt;
      
      &lt;box id="B16" x="50" onclick="this.ax1.doStart(); this.ax2.doStart()"&gt;
        &lt;animator name="ax1" attribute="x" to="400"
                  duration="1000" motion="easein"  start="false"/&gt;
        &lt;animator name="ax2" attribute="x" to="300"
                  duration="1000" motion="easeout" start="false"/&gt;
      &lt;/box&gt;
      &lt;view height="10"/&gt;
      &lt;box id="B17" x="50" onclick="this.bounce()"&gt;
        &lt;method name="bounce"&gt;
          this.animate("x",400,1000,false,{motion:'easeout'});
          this.animate("x",300,1000,false,{motion:'easein'});
        &lt;/method&gt;
      &lt;/box&gt;
      &lt;box id="B18" x="50" onclick="this.bounce()"&gt;
        &lt;method name="bounce"&gt;
          this.animate("x",400,1000,false,{motion:'easein'});
          this.animate("x",300,1000,false,{motion:'easeout'});
        &lt;/method&gt;
      &lt;/box&gt;
      &lt;box id="B19" x="50" onclick="this.bounce()"&gt;
        &lt;method name="bounce"&gt;
          this.animate("x",400,1000,false,{motion:'easein'});
          this.animate("x",300,1000,false,{motion:'easeout'});
        &lt;/method&gt;
      &lt;/box&gt;</em>
      &lt;simplelayout axis="y" spacing="10"/&gt;
    &lt;/view&gt;
  &lt;/view&gt;
  
  &lt;!-- The TEST and RESET buttons --&gt;
  &lt;view x="50" y="350"&gt;
    &lt;richbutton label="Test" x="50" cap="rightsheer"
                onclick="B15.ax1.doStart(); B15.ax2.doStart();
                         B16.ax1.doStart(); B16.ax2.doStart();
                         B17.bounce();  
                         B18.bounce();
                         B19.bounce();"/&gt;
    &lt;richbutton label="Reset" cap="leftsheer"
                onclick="B15.setX(50);
                         B16.setX(50);
                         B17.setX(50);
                         B18.setX(50);
                         B19.setX(50);
                  this.parent.P2.setDisplay(' ');"/&gt;
    &lt;simplelayout axis="x"/&gt;
  &lt;/view&gt;
&lt;/canvas&gt;
</example>

<h2>Using the <attribute>indirect</attribute> attribute</h2>

<p>The <attribute>indirect</attribute> attribute allows you to reverse
the direction in which an animation occurs while still arriving at the
same result.  In the example below, setting the
<attribute>indirect</attribute> attribute is set to <code>true</code>
for the animation on <varname>B23</varname>.  This causes the
animation to go to the left, rather than the right, disappearing off
the canvas, as it were, and reappearing on the right.  Setting the
<attribute>indirect</attribute> attribute to <code>true</code> in
animating the <attribute>rotation</attribute> attribute changes the
sense of the apparent motion from clockwise to counterclockwise.  Try
setting <attribute>indirect</attribute> to <code>true</code> on other
properties &#x2014; such as height, width, opacity &#x2014; to see the
effect.</p>

<example title="Indirect attribute">
&lt;canvas width="800" height="270" bgcolor="0xE5E1B0" &gt;
  &lt;!-- INCLUDES That provide framework for the example --&gt;
  &lt;include href="../animation_library.lzx"/&gt;
  
  &lt;!-- The EXAMPLE itself--&gt;
  &lt;view id="tutorial2" height="400" width="${parent.width}" visible="true"&gt;
    &lt;ruler name="rlr" height="250" y="0"/&gt;
    &lt;view height="30"/&gt;
    &lt;view height="200" y="40"&gt;
      &lt;view height="10"/&gt;   <em>
      &lt;box id="B22" x="50" onclick="this.anm.doStart()"&gt;
        &lt;animator name="anm" attribute="x" to="500"
                  duration="1000" start="false"/&gt;
      &lt;/box&gt;

      &lt;box id="B23" x="50" onclick="this.anm.doStart()"&gt;
        &lt;animator name="anm" attribute="x" to="500"
                  duration="1000" start="false" indirect="true"/&gt;
      &lt;/box&gt;
  </em>
      &lt;simplelayout axis="y" spacing="10"/&gt;
    &lt;/view&gt;
  &lt;/view&gt;

  &lt;!-- The TEST and RESET buttons --&gt;
  &lt;view x="50" y="250"&gt;
    &lt;richbutton label="Test" x="50" cap="rightsheer"
               onclick="B22.anm.doStart();B23.anm.doStart()"/&gt;
    &lt;richbutton label="Reset" cap="leftsheer"
               onclick="B22.setX(50);
                        B23.setX(50);
                        this.parent.P2.setDisplay(' ');"/&gt;
    &lt;simplelayout axis="x"/&gt;
  &lt;/view&gt;
&lt;/canvas&gt;
</example>

<h2>Animator Groups</h2>

<p>The <tagname link="true">animatorgroup</tagname> tag allows you to
combine the actions of several animators on a single object. The
animators can be set to operate simultaneously or sequentially.  In
the example below, animatorgroups are used to combine animations on
the <attribute>x</attribute> and <attribute>y</attribute> attributes
of the two red views. Notice that the <attribute>x</attribute>
attribute of <varname>B20</varname> has been set to linear motion
instead of the default <code>easeboth</code>.  In the case of
<varname>B21</varname> the motion of the <attribute>y</attribute>
animation has been set to <code>easeout</code>.  By clicking the
"test" button you can see how the these simple changes to the animator
parameters cause distinctly different movements.</p>

<p>The <tagname link="true">animatorgroup</tagname>
<attribute>process</attribute> attribute allows you to specify whether
the animators within an <tagname>animatorgroup</tagname> should be
processed sequentially or simultaneously. By default the actions are
performed simultaneously.  To see the difference, edit the example
below by specifying <code>process="sequential"</code>.</p>
 
<example title="Animator groups">
&lt;canvas width="800" height="400" bgcolor="0xE5E1B0"  &gt;
  &lt;!-- INCLUDES That provide framework for the example --&gt;
  &lt;include href="../animation_library.lzx"/&gt;
  
  &lt;!-- The EXAMPLE itself--&gt;
  &lt;view id="tutorial2" height="400" width="${parent.width}" visible="true"&gt;
    &lt;ruler name="rlr" height="350" y="0"/&gt;
    &lt;view height="30"/&gt;
    &lt;view height="200" y="40"&gt;
      &lt;view height="150" x="50"&gt;<em>
        &lt;box id="B20"  onclick="this.anm.doStart()"&gt;
          &lt;animatorgroup name="anm" start="false" process="simultaneous"&gt;
            &lt;animator attribute="x" from="0" to="300" duration="1000" motion="linear"/&gt;
            &lt;animator attribute="y" from="0" to="100" duration="1000"                /&gt;
          &lt;/animatorgroup&gt;
        &lt;/box&gt;
      &lt;/view&gt;
      &lt;view height="150" x="350"&gt;
        &lt;box id="B21" onclick="this.anm.doStart()"&gt;
          &lt;animatorgroup name="anm" start="false" process="simultaneous"&gt;
            &lt;animator attribute="x" from="0" to="300" duration="1000"                 /&gt;
            &lt;animator attribute="y" from="0" to="100" duration="1000" motion="easeout"/&gt;
          &lt;/animatorgroup&gt;
        &lt;/box&gt;</em>
      &lt;/view&gt;
      &lt;simplelayout axis="y" spacing="10"/&gt;
    &lt;/view&gt;
  &lt;/view&gt;

  &lt;!-- The TEST and RESET buttons --&gt;
  &lt;view x="50" y="350"&gt;
    &lt;richbutton label="Test" x="50" cap="rightsheer"
                onclick="B20.anm.doStart();
                         B21.anm.doStart()"/&gt;
    &lt;richbutton label="Reset" cap="leftsheer"
                onclick="B20.setX(0);B20.setY(0);
                         B21.setX(0);B21.setY(0);
                         this.parent.P2.setDisplay(' ');"/&gt;
    &lt;simplelayout axis="x"/&gt;
  &lt;/view&gt;
&lt;/canvas&gt;
</example>

<p> Animatorgroups can be contained within animatorgroups allowing for the encapsulation of more complex behavior.
This next example illustrates that point, by having the view now return back to its original position which requires
the object to be animated along both the x and y axis simultaneously after its initial movements on them separately.</p>

<example class="program" title="animatorgroup-2">
&lt;canvas height="210"&gt;
  &lt;view bgcolor="red" width="100" height="100" onclick="this.outeranimatorgroup.doStart()"&gt;
    &lt;text align="center" valign="middle"&gt;Click Me!&lt;/text&gt;    
    &lt;animatorgroup name="outeranimatorgroup" process="sequential" start="false"&gt;
      &lt;animator attribute="x" to="100" duration="1000"/&gt;
      &lt;animator attribute="y" to="100" duration="1000"/&gt;
      &lt;animatorgroup  process="simultaneous" duration="1000"&gt;
        &lt;animator attribute="x" to="0"/&gt;
        &lt;animator attribute="y" to="0"/&gt;
      &lt;/animatorgroup&gt;
    &lt;/animatorgroup&gt;
  &lt;/view&gt;
&lt;/canvas&gt;
</example>


<p>Note that in the code above there was no duration set for the x and
y animators of the interior <tagname>animatorgroup</tagname>.
Attributes such as <attribute>duration</attribute>,
<attribute>x</attribute>, <attribute>y</attribute>,
<attribute>width</attribute>, etc. can be defined in an
<tagname>animatorgroup</tagname> and these values will be adopted by
every subanimator unless they already have that attribute defined for
themselves. If, as in the example above, a
<attribute>duration</attribute> value is assigned to an animated
group, it does not necessarily mean that the animatorgroup will be
confined to that amount of time.  It means that every subanimator may
use that duration. If <code>process='simultaneous'</code> and each
subanimator uses the group <attribute>duration</attribute> as their
value then the length of total time for all subanimators would equal
the duration time for the animatorgroup</p>

<h2><a name="animating_layout">Animating Layout</a></h2>

<p>You can animate any attribute that can be modified at runtime. For
example, the following example shows the effect you can get by
animating a layout. Because layout encompasses several attributes we
have simplified this example by having the layout return to its
initial state &#x2014; there is no "reset" button.</p>

<example title="Animating Layout">
&lt;canvas width="800" height="185" bgcolor="0xE5E1B0"&gt;
  &lt;!-- INCLUDES That provide framework for the example --&gt;
  &lt;include href="../animation_library.lzx"/&gt;
  
  &lt;!-- The EXAMPLE itself--&gt;
  &lt;view id="tutorial2" height="200" width="${parent.width}" visible="true"&gt;
    &lt;ruler name="rlr" height="150" y="0"/&gt;
    &lt;view height="30"/&gt;
    &lt;view height="60" y="40"&gt;
      &lt;view id="V01" x="50"&gt;
        &lt;borderedbox/&gt;
        &lt;borderedbox/&gt;
        &lt;borderedbox/&gt;
        &lt;borderedbox/&gt;
        <em>
        
        &lt;simplelayout name="lyt" axis="x" spacing="5"&gt;
          &lt;animatorgroup name="anm" start="false" process="sequential"&gt;
            &lt;animator attribute="spacing" from="5"   to="50"  duration="1000"/&gt;
            &lt;animator attribute="spacing" from="50"  to="-49" duration="1000"/&gt;
            &lt;animator attribute="spacing" from="-49" to="5"   duration="1000"/&gt;
          &lt;/animatorgroup&gt;</em>
        &lt;/simplelayout&gt;
      &lt;/view&gt;
    &lt;/view&gt;
    
    &lt;!-- The TEST button --&gt;
    &lt;view x="50" y="150"&gt;
      &lt;richbutton label="Test" x="50" cap="both"
                  onclick="V01.lyt.anm.doStart()"/&gt;
    &lt;/view&gt;
  &lt;/view&gt;
&lt;/canvas&gt;
</example>
<h2>Everything Animates</h2>
<p>Now that you've seen how animation works you can explore animating all different kinds of attributes.  
Here is a hint: try giving a view a "hidden" attribute, say "charm"
that is constrained to the value of other attributes, and then animating "charm."    </p>
 <p>
For example, often, you need a there-and-back animation. This can be a bother, since the obvious way to do it
requires two animators, and adjusting properties within an animator group can be tricky.</p>

<p>A simple workaround is to use an animated value as the square root of
the destination value. This gives you that kind of there-and-back
behavior with a single animator.</p>

<example title="compound behavior in single animator">
&lt;canvas height="50"&gt;
  &lt;view width="30" height="30" bgcolor="red"
        x="${225 - (this.sqrtx * this.sqrtx)}"&gt;
    &lt;attribute name="sqrtx" value="-15"/&gt;
    &lt;animator attribute="sqrtx" from ="-15" to="15"
              duration="3000" repeat="Infinity"/&gt;
  &lt;/view&gt;
&lt;/canvas&gt;
</example>
<?ignore
Topics for future additions to this chapter:
 
 offset in animations
 The  onstop  event
 Chain animations of different events
 Call methods after animations finish

 last animation gives target destination
 difference between scripted and tag-based animations
 chaining delegates 
 The animator group
h.Animated resources (animated swfs, "animated animations")
i. Clip regions and animation
 
 Using  hidden  variable to coordinate multiple animations:
i. Constrain animations to varialble
k.  animators by reference
 

LzAnimator animates an attribute of another object over time.
It does this by generating a new number eveytime the iterate
method is called. This sequence of numbers generated begins with the <b>from
</b>value and ends with the <b>to</b> value weithin the
time specified by <b>duration</b>. If <b>isRelative</b>
is <b>true</b> then the value generated is added to the binding property,
and if it is <b>false</b> the value replaces the binding property with a
new value.
?>
</body>
</html>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2001-2004 Laszlo Systems, Inc.  All Rights Reserved.              *
* Use is subject to license terms.                                            *
* X_LZ_COPYRIGHT_END ****************************************************** -->
